#pragma once
#include "UltimateSubsystemRegistryPrecompiled.h"
#include "UltimateSubsystemRegistryPrerequisites.h"
#include "UltimateSubsystem.h"
#include "UltimateSubsystemRegistry.h"



class _UltimateSubsystemRegistryExport UltimateSoundSubsystem : public UltimateSubsystem
{

public:

	virtual Ogre::String  getSubsystemName()
	{
		return SOUND_SUBSYSTEM;
	}


	UltimateSoundSubsystem();
	UltimateSoundSubsystem(int argc, char** argv);

	virtual void helloAudioWorld()=0;

	virtual Ogre::Vector3 getAudioListenerPosition()=0;
	virtual Ogre::Vector3 getAudioListenerDirection()=0;
	
	virtual void setAudioListenerPose(Ogre::Vector3 pos, Ogre::Vector3 dir)=0;

	virtual void createAudioWithName(
		Ogre::String name, Ogre::String filePath, bool looping,
		float pitch, Ogre::Vector3 position)=0;

	virtual void setAudioWithName(
		Ogre::String name, Ogre::String filePath, bool looping,
		float pitch, Ogre::Vector3 position)=0;

	virtual void playAudioByName(Ogre::String name)=0;

	virtual void playAudioFromFile(Ogre::String filePath, bool looping,
		float pitch, Ogre::Vector3 position)=0;

	virtual void stopAudioByName(Ogre::String name)=0;

	virtual void stopAllAudioSource()=0;

	virtual void deleteAllAudioSource()=0;
    
	virtual ~UltimateSoundSubsystem()=0; 
};

/*
class GameAudio
{
	std::map<std::string, ALuint> sourceMap;
	int currentSourceMapIndex;
	
	ALuint loadFile(const char* filename)
	{
		ALenum error;
		ALuint newBuffer;
		ALUT_SAFE_CALL(newBuffer = alutCreateBufferFromFile(filename), "Cannot load audio file: " + Ogre::String(filename));        
		return newBuffer;
	}

	void createSource(ALuint* source)
	{
		AL_SAFE_CALL(alGenSources (1, source), "Unable to generate source");
	}

public:
	GameAudio(int argc, char** argv)
	{
		printf("*** Initializing OpenAL ***\n");
        
        alutInit (&argc, argv);

		ALenum error;
		sourceMap.clear();

		helloAudioWorld();

		error = alutGetError();
		if(error != AL_NO_ERROR)
		{
			// Ogre::LogManager::getSingleton().logMessage("Cannot load audio file: "+ Ogre::String(alutGetErrorString(error)));
		}

    }

	// Hello World for OpenAL
	void helloAudioWorld()
	{
		ALuint helloBuffer, helloSource;

		helloBuffer = alutCreateBufferHelloWorld ();

		alGenSources (1, &helloSource);
		alSourcei (helloSource, AL_BUFFER, helloBuffer);

		alSourcei (helloSource, AL_LOOPING, AL_FALSE);
		alSourcei (helloSource, AL_GAIN, 10);
		alSourcef (helloSource, AL_PITCH, 1.0);
		
		float musicVolume = 10;
		alSourcei (helloSource, AL_GAIN, musicVolume);

		alListener3f(AL_POSITION, 0,0,0);
		alSource3f(helloSource, AL_POSITION, -1,0,0);

		alSourcePlay (helloSource);
	}

	// Create audio source with: name, filepath (buffer), loop, pitch, position
	// Does not play the actual audio
	void createAudioWithName(
		Ogre::String name, Ogre::String filePath, bool looping = false,
		float pitch = 1.0, Ogre::Vector3 position = Ogre::Vector3::ZERO)
	{

		ALuint buffer = loadFile(filePath.c_str());
		ALuint source;
		createSource(&source);

		AL_SAFE_CALL(alSourcei (source, AL_BUFFER, buffer), "unable to bind buffer");
		if (looping)
			AL_SAFE_CALL(alSourcei (source, AL_LOOPING, AL_TRUE), "unable to set looping");
		AL_SAFE_CALL(alSourcef (source, AL_PITCH, pitch), "unable to set pitch");
		AL_SAFE_CALL(alSource3f (source, AL_POSITION, position.x, position.y, position.z), "unable to set position");

		sourceMap[name.c_str()] = source;

	}

	// Alter the named audio source with: filepath (buffer), loop, pitch, position
	// Does not play the actual audio
	void setAudioWithName(
		Ogre::String name, Ogre::String filePath, bool looping = false,
		float pitch = 1.0, Ogre::Vector3 position = Ogre::Vector3::ZERO)
	{

		ALuint buffer = loadFile(filePath.c_str());
		ALuint source = sourceMap[name.c_str()];

		AL_SAFE_CALL(alSourcei (source, AL_BUFFER, buffer), "unable to bind buffer");
		if (looping)
			AL_SAFE_CALL(alSourcei (source, AL_LOOPING, AL_TRUE), "unable to set looping");
		AL_SAFE_CALL(alSourcef (source, AL_PITCH, pitch), "unable to set pitch");
		AL_SAFE_CALL(alSource3f (source, AL_POSITION, position.x, position.y, position.z), "unable to set position");

	}

	// Plays the named audio
	void playAudioByName(Ogre::String name)
	{
		ALuint source = sourceMap[name.c_str()];
		AL_SAFE_CALL(alSourcePlay (source), "unable to play title source");
	}

	// Create audio source: filepath (buffer), loop, pitch, position
	// Plays the actual audio, but doesnt store it
	void palyAudioFromFile(Ogre::String filePath, bool looping = false,
		float pitch = 1.0, Ogre::Vector3 position = Ogre::Vector3::ZERO)
	{
		ALuint buffer = loadFile(filePath.c_str());
		ALuint source;
		createSource(&source);

		AL_SAFE_CALL(alSourcei (source, AL_BUFFER, buffer), "unable to bind buffer");
		if (looping)
			AL_SAFE_CALL(alSourcei (source, AL_LOOPING, AL_TRUE), "unable to set looping");
		AL_SAFE_CALL(alSourcef (source, AL_PITCH, pitch), "unable to set pitch");
		AL_SAFE_CALL(alSource3f (source, AL_POSITION, position.x, position.y, position.z), "unable to set position");
		
        AL_SAFE_CALL(alSourcePlay (source), "unable to play source");
	}

	// Stops named audio source
	void stopAudioByName(Ogre::String name)
	{
		ALuint source = sourceMap[name.c_str()];
		AL_SAFE_CALL(alSourceStop (source), "unable to stop" + name + "source");
	}

	// Stops all audio
	void stopAllAudioSource()
	{
		std::map<std::string, ALuint>::iterator i = sourceMap.begin();
		for( ; i != sourceMap.end(); ++i )
		{
			// i->first is the key
			// i->second is it's value
			AL_SAFE_CALL(alSourceStop(i->second), "unable to stop" + i->first + "source");
		}

	}
	
	void deleteAllAudioSource()
	{
		stopAllAudioSource();
		sourceMap.clear();
	}
    
    ~GameAudio()
    {
        printf("*** Shutting down OpenAL ***\n");

		deleteAllAudioSource();
        
        alutExit();
    }   
};
*/